package com.ming.liteflow.core.node;

import com.ming.common.dynamic.code.IClassExecuter;
import com.ming.common.dynamic.code.IStringCompiler;
import com.ming.common.dynamic.code.RunClassHandler;
import com.ming.common.dynamic.code.RunSourceHandler;
import com.ming.common.dynamic.code.config.RunSourceProperties;
import com.ming.common.dynamic.code.core.ClassExecuter;
import com.ming.common.dynamic.code.core.StringJavaCompiler;
import com.ming.common.dynamic.code.dto.ClassBean;
import com.ming.common.dynamic.code.dto.ExecuteResult;
import com.ming.common.dynamic.code.dto.Parameters;
import com.ming.common.dynamic.code.exception.BaseDynamicException;
import com.ming.common.dynamic.code.factory.AbstractCompilerFactory;
import com.ming.common.dynamic.code.factory.StandardCompilerFactory;
import com.ming.common.dynamic.loader.SpringContextUtil;
import com.ming.liteflow.core.exec.ELExecUtil;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CmpCompiler {

    public static final String code1 = "package com.ming.liteflow.cmp;\n" +
            "import com.yomahub.liteflow.annotation.LiteflowComponent;\n" +
            "import com.yomahub.liteflow.core.NodeComponent;\n" +
            "\n" +
            "@LiteflowComponent(\"aaa\")\n" +
            "public class Cmp1 extends NodeComponent {\n" +
            "\t@Override\n" +
            "\tpublic void process() {\n" +
            "\t\tSystem.out.println(\"ACmp executed!\");\n" +
            "\t}\n" +
            "\n" +
            "}";

    public static final String code2 = "package com.ming.liteflow.cmp;\n" +
            "import com.yomahub.liteflow.annotation.LiteflowComponent;\n" +
            "import com.yomahub.liteflow.core.NodeComponent;\n" +
            "\n" +
            "@LiteflowComponent(\"aaa\")\n" +
            "public class Cmp1 extends NodeComponent {\n" +
            "\t@Override\n" +
            "\tpublic void process() {\n" +
            "\t\tSystem.out.println(\"ACmp2 executed!\");\n" +
            "\t}\n" +
            "\n" +
            "}";

    public static void test2(NodeInfo nodeInfo) throws BaseDynamicException, MalformedURLException {
        // 根据实际需求创建执行源码方法类,先创建以下构造实例必要参数。
        // 安全替换（key:待替换的类名,例如:java/io/File，value:替换成的类名,例如:com/zhg2yqq/wheels/dynamic/code/hack/HackFile）
        Map<String, String> hackers = new HashMap<>();
        // 是否需要返回编译、调用源码方法运行用时
        RunSourceProperties calTime = new RunSourceProperties();
        // 编译器，默认使用Janino编译工具
        AbstractCompilerFactory compilerFactory = new StandardCompilerFactory(null);
        IStringCompiler compiler = new StringJavaCompiler(compilerFactory);
        // 执行器
        IClassExecuter<ExecuteResult> executer = new ClassExecuter();

        RunSourceHandler handler = new RunSourceHandler(compiler, executer, calTime, hackers);

        Parameters pars1 = new Parameters();
        ExecuteResult result1 = handler.runMethod(code1, "process",pars1);
        //System.out.println(result1.getReturnVal());

        //CmpUtil.createCommonNode(nodeInfo);
        System.out.println(ELExecUtil.exec("THEN(aaa);"));

        // 重新编译加载源码类
        Parameters pars2 = new Parameters();
        ExecuteResult result2 = handler.runMethod(code2,"process", pars2, false, true);
        //System.out.println(result2.getReturnVal());

        //CmpUtil.createCommonNode(nodeInfo);
        System.out.println(ELExecUtil.exec("THEN(aaa);"));
    }

    public static void testClass(NodeInfo nodeInfo) throws BaseDynamicException, MalformedURLException {
        // 根据实际需求创建执行源码方法类,先创建以下构造实例必要参数。
        // 安全替换（key:待替换的类名,例如:java/io/File，value:替换成的类名,例如:com/zhg2yqq/wheels/dynamic/code/hack/HackFile）
        Map<String, String> hackers = new HashMap<>();
        // 是否需要返回编译、调用源码方法运行用时
        RunSourceProperties calTime = new RunSourceProperties();
        // 编译器，默认使用Janino编译工具
        AbstractCompilerFactory compilerFactory = new StandardCompilerFactory(null);
        IStringCompiler compiler = new StringJavaCompiler(compilerFactory);
        // 执行器
        IClassExecuter<ExecuteResult> executer = new ClassExecuter();
        RunClassHandler handler = new RunClassHandler(compiler, executer, calTime, hackers);

        ClassBean classBean = handler.loadClassFromSource(code1);
        Class<?> clazz = classBean.getClazz();
        //nodeInfo.setClazz(clazz);
        //CmpUtil.createCommonNode(nodeInfo);
        System.out.println(ELExecUtil.exec("THEN(aaa);"));

        handler.loadClassFromSource(code2);
        //CmpUtil.createCommonNode(nodeInfo);
        System.out.println(ELExecUtil.exec("THEN(aaa);"));
    }
}
